"""
图形用户界面模块
负责创建和管理所有GUI组件
使用Tkinter构建用户友好的日程管理界面

模块结构：
1. 主窗口类 (ScheduleGUI)
2. 对话框类 (各种功能对话框)
3. 工具类和函数
"""

import tkinter as tk
from tkinter import ttk, messagebox, simpledialog, scrolledtext
from datetime import datetime, timedelta
import logging
import os
from utils import validate_schedule_data, format_datetime, get_priority_text, get_priority_color


# =============================================================================
# 主窗口类 - ScheduleGUI
# =============================================================================

class ScheduleGUI:
    """
    智能日程管理助手主窗口
    负责管理整个应用程序的用户界面
    """
    
    def __init__(self, db_manager, net_sim, reminder_manager, file_exporter, config):
        """
        初始化主窗口
        
        Args:
            db_manager: 数据库管理器实例
            net_sim: 网络模拟器实例  
            reminder_manager: 提醒管理器实例
            file_exporter: 文件导出器实例
            config: 配置管理器实例
        """
        self.db_manager = db_manager
        self.net_sim = net_sim
        self.reminder_manager = reminder_manager
        self.file_exporter = file_exporter
        self.config = config
        self.logger = logging.getLogger(__name__)
        
        # GUI组件
        self.root = None
        self.tree = None
        self.status_var = None
        self.search_var = None
        self.reminder_service = None
        self.resize_timer = None
        
        # 初始化GUI
        self._initialize_gui()
        
        # 初始化提醒服务
        self._initialize_reminder_service()
    
    def _initialize_gui(self):
        """初始化GUI组件"""
        self.root = tk.Tk()
        self.root.title("智能日程管理助手")
        
        # 设置窗口大小和位置
        window_width = self.config.get("gui.window_width", 1000)
        window_height = self.config.get("gui.window_height", 700)
        self.root.geometry(f"{window_width}x{window_height}")
        
        # 设置窗口图标
        self._set_window_icon()
        
        # 创建菜单栏
        self._create_menu()
        
        # 创建主内容区域
        self._create_main_content()
        
        # 绑定事件
        self._bind_events()
        
        self.logger.info("GUI界面初始化完成")
    
    def _initialize_reminder_service(self):
        """初始化提醒服务"""
        self.reminder_service = self.reminder_manager.create_reminder_service(
            "main", 
            self.show_reminder
        )
        
        # 配置提醒服务
        reminder_check_interval = self.config.get("reminder.check_interval", 30)
        self.reminder_service.set_check_interval(reminder_check_interval)
        self.reminder_service.enable_sound(self.config.get("reminder.play_sound", True))
        
        # 启动提醒服务
        self.reminder_service.start()
        self.logger.info("提醒服务已启动")
    
    def _set_window_icon(self):
        """设置窗口图标"""
        try:
            icon_path = "resources/icon.png"
            if os.path.exists(icon_path):
                icon = tk.PhotoImage(file=icon_path)
                self.root.iconphoto(True, icon)
                self.logger.debug("窗口图标设置成功")
        except Exception as e:
            self.logger.warning(f"设置窗口图标失败: {e}")
    
    def _create_menu(self):
        """创建菜单栏"""
        menubar = tk.Menu(self.root)
        
        # 文件菜单
        file_menu = tk.Menu(menubar, tearoff=0)
        file_menu.add_command(label="新建日程", command=self.show_add_schedule_dialog, accelerator="Ctrl+N")
        file_menu.add_separator()
        file_menu.add_command(label="导出日程", command=self.show_export_dialog)
        file_menu.add_command(label="系统备份", command=self.create_backup)
        file_menu.add_separator()
        file_menu.add_command(label="退出", command=self.on_closing, accelerator="Ctrl+Q")
        menubar.add_cascade(label="文件", menu=file_menu)
        
        # 编辑菜单
        edit_menu = tk.Menu(menubar, tearoff=0)
        edit_menu.add_command(label="刷新", command=self.refresh_schedules, accelerator="F5")
        edit_menu.add_command(label="删除选中", command=self.delete_selected_schedule, accelerator="Delete")
        edit_menu.add_separator()
        edit_menu.add_command(label="搜索日程", command=self.show_search_dialog, accelerator="Ctrl+F")
        menubar.add_cascade(label="编辑", menu=edit_menu)
        
        # 视图菜单
        view_menu = tk.Menu(menubar, tearoff=0)
        view_menu.add_command(label="今日日程", command=self.show_today_schedules)
        view_menu.add_command(label="本周日程", command=self.show_week_schedules)
        view_menu.add_command(label="所有日程", command=self.show_all_schedules)
        view_menu.add_separator()
        view_menu.add_command(label="统计信息", command=self.show_statistics)
        menubar.add_cascade(label="视图", menu=view_menu)
        
        # 工具菜单
        tools_menu = tk.Menu(menubar, tearoff=0)
        tools_menu.add_command(label="网络测试", command=self.test_network)
        tools_menu.add_command(label="提醒设置", command=self.show_reminder_settings)
        tools_menu.add_command(label="系统设置", command=self.show_system_settings)
        menubar.add_cascade(label="工具", menu=tools_menu)
        
        # 帮助菜单
        help_menu = tk.Menu(menubar, tearoff=0)
        help_menu.add_command(label="使用说明", command=self.show_help)
        help_menu.add_command(label="查看日志", command=self.show_logs)
        help_menu.add_separator()
        help_menu.add_command(label="关于", command=self.show_about)
        menubar.add_cascade(label="帮助", menu=help_menu)
        
        self.root.config(menu=menubar)
        
        # 绑定快捷键
        self._bind_shortcuts()
    
    def _bind_shortcuts(self):
        """绑定快捷键"""
        self.root.bind("<Control-n>", lambda e: self.show_add_schedule_dialog())
        self.root.bind("<Control-q>", lambda e: self.on_closing())
        self.root.bind("<F5>", lambda e: self.refresh_schedules())
        self.root.bind("<Delete>", lambda e: self.delete_selected_schedule())
        self.root.bind("<Control-f>", lambda e: self.show_search_dialog())
    
    def _create_main_content(self):
        """创建主内容区域"""
        # 创建主框架
        main_frame = ttk.Frame(self.root)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # 创建工具栏
        self._create_toolbar(main_frame)
        
        # 创建日程列表
        self._create_schedule_list(main_frame)
        
        # 创建状态栏
        self._create_status_bar(main_frame)
    
    def _create_toolbar(self, parent):
        """创建工具栏"""
        toolbar = ttk.Frame(parent)
        toolbar.pack(fill=tk.X, pady=(0, 5))
        
        # 工具栏按钮
        ttk.Button(toolbar, text="新建日程", command=self.show_add_schedule_dialog).pack(side=tk.LEFT, padx=2)
        ttk.Button(toolbar, text="刷新", command=self.refresh_schedules).pack(side=tk.LEFT, padx=2)
        ttk.Button(toolbar, text="今日日程", command=self.show_today_schedules).pack(side=tk.LEFT, padx=2)
        ttk.Button(toolbar, text="删除选中", command=self.delete_selected_schedule).pack(side=tk.LEFT, padx=2)
        
        # 搜索框
        ttk.Label(toolbar, text="搜索:").pack(side=tk.LEFT, padx=(20, 2))
        self.search_var = tk.StringVar()
        search_entry = ttk.Entry(toolbar, textvariable=self.search_var, width=20)
        search_entry.pack(side=tk.LEFT, padx=2)
        search_entry.bind("<Return>", lambda e: self.search_schedules())
        ttk.Button(toolbar, text="搜索", command=self.search_schedules).pack(side=tk.LEFT, padx=2)
        
        # 清空搜索按钮
        ttk.Button(toolbar, text="清空", command=self.clear_search).pack(side=tk.LEFT, padx=2)
    
    def _create_schedule_list(self, parent):
        """创建日程列表显示"""
        # 创建Treeview框架
        tree_frame = ttk.Frame(parent)
        tree_frame.pack(fill=tk.BOTH, expand=True)
        
        # 创建Treeview
        columns = ("id", "标题", "开始时间", "结束时间", "优先级", "类别", "状态")
        self.tree = ttk.Treeview(tree_frame, columns=columns, show="headings", selectmode="browse")
        
        # 设置列标题和宽度
        column_configs = [
            ("id", "ID", 50),
            ("标题", "标题", 200),
            ("开始时间", "开始时间", 150),
            ("结束时间", "结束时间", 150),
            ("优先级", "优先级", 80),
            ("类别", "类别", 100),
            ("状态", "状态", 80)
        ]
        
        for col, heading, width in column_configs:
            self.tree.heading(col, text=heading)
            self.tree.column(col, width=width)
        
        # 添加滚动条
        scrollbar = ttk.Scrollbar(tree_frame, orient=tk.VERTICAL, command=self.tree.yview)
        self.tree.configure(yscrollcommand=scrollbar.set)
        
        # 布局
        self.tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        
        # 绑定事件
        self.tree.bind("<Double-1>", self.on_item_double_click)
        self.tree.bind("<Button-3>", self.on_right_click)
        
        # 初始加载数据
        self.refresh_schedules()
    
    def _create_status_bar(self, parent):
        """创建状态栏"""
        status_frame = ttk.Frame(parent)
        status_frame.pack(fill=tk.X, pady=(5, 0))
        
        self.status_var = tk.StringVar()
        self.status_var.set("就绪")
        status_label = ttk.Label(status_frame, textvariable=self.status_var, relief=tk.SUNKEN)
        status_label.pack(side=tk.LEFT, fill=tk.X, expand=True)
        
        # 显示提醒服务状态
        self.reminder_status_var = tk.StringVar()
        self.reminder_status_var.set("提醒服务: 运行中")
        reminder_status_label = ttk.Label(status_frame, textvariable=self.reminder_status_var, relief=tk.SUNKEN)
        reminder_status_label.pack(side=tk.RIGHT)
        
        # 更新状态栏信息
        self.update_status_bar()
    
    def _bind_events(self):
        """绑定事件"""
        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
        self.resize_timer = None
        self.root.bind("<Configure>", self.on_window_resize_debounced)
    
    def on_window_resize_debounced(self, event):
        """防抖处理窗口大小变化"""
        if event.widget == self.root:
            if self.resize_timer:
                self.root.after_cancel(self.resize_timer)
            self.resize_timer = self.root.after(500, lambda: self.on_window_resize(event))
    
    def on_window_resize(self, event):
        """处理窗口大小变化事件"""
        if event.widget == self.root:
            self.config.set("gui.window_width", self.root.winfo_width())
            self.config.set("gui.window_height", self.root.winfo_height())
    
    # =========================================================================
    # 公共方法 - 日程管理
    # =========================================================================
    
    def refresh_schedules(self, date_str=None):
        """刷新日程列表"""
        try:
            # 清空现有数据
            for item in self.tree.get_children():
                self.tree.delete(item)
            
            if date_str is None:
                date_str = datetime.now().strftime("%Y-%m-%d")
            
            schedules = self.db_manager.get_schedules_by_date(date_str)
            
            # 添加到Treeview
            for schedule in schedules:
                self.tree.insert("", "end", values=(
                    schedule['id'],
                    schedule['title'],
                    schedule['start_time'],
                    schedule['end_time'] or "",
                    get_priority_text(schedule['priority']),
                    schedule['category'],
                    schedule['status']
                ))
            
            self.status_var.set(f"已加载 {len(schedules)} 个日程 (日期: {date_str})")
            
        except Exception as e:
            self.logger.error(f"刷新日程列表失败: {e}")
            self.status_var.set("加载日程失败")
            messagebox.showerror("错误", f"加载日程失败: {str(e)}")
    
    def show_today_schedules(self):
        """显示今日日程"""
        today = datetime.now().strftime("%Y-%m-%d")
        self.refresh_schedules(today)
        self.status_var.set("显示今日日程")
    
    def show_week_schedules(self):
        """显示本周日程"""
        try:
            # 计算本周的日期范围
            today = datetime.now()
            start_of_week = today - timedelta(days=today.weekday())
            end_of_week = start_of_week + timedelta(days=6)
            
            # 清空现有数据
            for item in self.tree.get_children():
                self.tree.delete(item)
            
            # 获取本周所有日程
            all_schedules = self.db_manager.get_all_schedules(limit=200)
            week_schedules = []
            
            for schedule in all_schedules:
                try:
                    schedule_date = datetime.strptime(schedule['start_time'], '%Y-%m-%d %H:%M:%S')
                    if start_of_week.date() <= schedule_date.date() <= end_of_week.date():
                        week_schedules.append(schedule)
                except ValueError:
                    continue
            
            # 添加到Treeview
            for schedule in week_schedules:
                self.tree.insert("", "end", values=(
                    schedule['id'],
                    schedule['title'],
                    schedule['start_time'],
                    schedule['end_time'] or "",
                    get_priority_text(schedule['priority']),
                    schedule['category'],
                    schedule['status']
                ))
            
            self.status_var.set(f"已加载 {len(week_schedules)} 个本周日程")
            
        except Exception as e:
            self.logger.error(f"加载本周日程失败: {e}")
            self.status_var.set("加载日程失败")
            messagebox.showerror("错误", f"加载本周日程失败: {str(e)}")
    
    def show_all_schedules(self):
        """显示所有日程"""
        try:
            # 清空现有数据
            for item in self.tree.get_children():
                self.tree.delete(item)
            
            schedules = self.db_manager.get_all_schedules(limit=100)
            
            # 添加到Treeview
            for schedule in schedules:
                self.tree.insert("", "end", values=(
                    schedule['id'],
                    schedule['title'],
                    schedule['start_time'],
                    schedule['end_time'] or "",
                    get_priority_text(schedule['priority']),
                    schedule['category'],
                    schedule['status']
                ))
            
            self.status_var.set(f"已加载 {len(schedules)} 个日程 (全部)")
            
        except Exception as e:
            self.logger.error(f"加载所有日程失败: {e}")
            self.status_var.set("加载日程失败")
    
    def search_schedules(self):
        """搜索日程"""
        keyword = self.search_var.get().strip()
        if not keyword:
            messagebox.showwarning("警告", "请输入搜索关键词")
            return
        
        try:
            # 清空现有数据
            for item in self.tree.get_children():
                self.tree.delete(item)
            
            schedules = self.db_manager.search_schedules(keyword)
            
            # 添加到Treeview
            for schedule in schedules:
                self.tree.insert("", "end", values=(
                    schedule['id'],
                    schedule['title'],
                    schedule['start_time'],
                    schedule['end_time'] or "",
                    get_priority_text(schedule['priority']),
                    schedule['category'],
                    schedule['status']
                ))
            
            self.status_var.set(f"搜索 '{keyword}' 找到 {len(schedules)} 个日程")
            
        except Exception as e:
            self.logger.error(f"搜索日程失败: {e}")
            self.status_var.set("搜索失败")
            messagebox.showerror("错误", f"搜索失败: {str(e)}")
    
    def clear_search(self):
        """清空搜索"""
        self.search_var.set("")
        self.refresh_schedules()
    
    def delete_selected_schedule(self):
        """删除选中的日程"""
        selection = self.tree.selection()
        if not selection:
            messagebox.showwarning("警告", "请先选择一个日程")
            return
        
        item = self.tree.item(selection[0])
        values = item['values']
        schedule_id = values[0]
        title = values[1]
        
        if messagebox.askyesno("确认删除", f"确定要删除日程 '{title}' 吗？"):
            if self.db_manager.delete_schedule(schedule_id):
                self.refresh_schedules()
                self.status_var.set("日程删除成功")
            else:
                messagebox.showerror("错误", "删除日程失败")
    
    def mark_schedule_completed(self, schedule_id):
        """标记日程为已完成"""
        if self.db_manager.update_schedule_status(schedule_id, 'completed'):
            self.refresh_schedules()
            self.status_var.set("日程状态已更新")
        else:
            messagebox.showerror("错误", "更新日程状态失败")
    
    # =========================================================================
    # 公共方法 - 对话框显示
    # =========================================================================
    
    def show_add_schedule_dialog(self):
        """显示添加日程对话框"""
        dialog = AddScheduleDialog(self.root, self.db_manager, self.config)
        if dialog.result:
            self.refresh_schedules()
            self.status_var.set("日程添加成功")
    
    def show_edit_schedule_dialog(self, schedule_id):
        """显示编辑日程对话框"""
        schedule = self.db_manager.get_schedule(schedule_id)
        if not schedule:
            messagebox.showerror("错误", "找不到指定的日程")
            return
        
        dialog = EditScheduleDialog(self.root, self.db_manager, schedule, self.config)
        if dialog.result:
            self.refresh_schedules()
            self.status_var.set("日程更新成功")
    
    def show_search_dialog(self):
        """显示搜索对话框"""
        dialog = SearchDialog(self.root, self.db_manager)
        if dialog.result and dialog.result.get('keyword'):
            keyword = dialog.result['keyword']
            self.search_var.set(keyword)
            self.search_schedules()
    
    def show_export_dialog(self):
        """显示导出对话框"""
        dialog = ExportDialog(self.root, self.file_exporter)
        if dialog.result:
            self.status_var.set("导出任务已开始")
    
    def show_reminder_settings(self):
        """显示提醒设置对话框"""
        dialog = ReminderSettingsDialog(self.root, self.reminder_service, self.config)
        if dialog.result:
            self.status_var.set("提醒设置已更新")
    
    def show_system_settings(self):
        """显示系统设置对话框"""
        dialog = SystemSettingsDialog(self.root, self.config)
        if dialog.result:
            self.status_var.set("系统设置已更新")
            self.apply_system_settings()
    
    def show_statistics(self):
        """显示统计信息"""
        try:
            stats = self.db_manager.get_statistics()
            
            stats_window = tk.Toplevel(self.root)
            stats_window.title("日程统计")
            stats_window.geometry("300x250")
            stats_window.transient(self.root)
            stats_window.grab_set()
            
            frame = ttk.Frame(stats_window, padding="10")
            frame.pack(fill=tk.BOTH, expand=True)
            
            # 显示统计信息
            ttk.Label(frame, text="日程统计", font=("Arial", 12, "bold")).grid(row=0, column=0, columnspan=2, pady=5)
            
            statistics = [
                ("总日程数:", stats.get('total', 0)),
                ("今日日程:", stats.get('today', 0)),
                ("待办日程:", stats.get('by_status', {}).get('pending', 0)),
                ("已完成:", stats.get('by_status', {}).get('completed', 0)),
                ("高优先级:", stats.get('by_priority', {}).get(3, 0)),
                ("中优先级:", stats.get('by_priority', {}).get(2, 0)),
                ("低优先级:", stats.get('by_priority', {}).get(1, 0)),
            ]
            
            for i, (label, value) in enumerate(statistics, 1):
                ttk.Label(frame, text=label).grid(row=i, column=0, sticky="w", pady=2)
                ttk.Label(frame, text=str(value)).grid(row=i, column=1, sticky="w", pady=2)
            
            ttk.Button(frame, text="关闭", command=stats_window.destroy).grid(row=len(statistics)+1, column=0, columnspan=2, pady=10)
            
        except Exception as e:
            self.logger.error(f"显示统计信息失败: {e}")
            messagebox.showerror("错误", f"获取统计信息失败: {str(e)}")
    
    def show_reminder(self, schedule):
        """显示提醒窗口"""
        reminder_window = tk.Toplevel(self.root)
        reminder_window.title("日程提醒")
        reminder_window.geometry("400x200")
        reminder_window.transient(self.root)
        reminder_window.grab_set()
        
        # 设置窗口始终置顶
        reminder_window.attributes('-topmost', True)
        
        frame = ttk.Frame(reminder_window, padding="15")
        frame.pack(fill=tk.BOTH, expand=True)
        
        # 提醒图标和标题
        ttk.Label(frame, text="🔔 日程提醒", font=("Arial", 14, "bold")).pack(pady=5)
        
        # 日程信息
        ttk.Label(frame, text=f"标题: {schedule['title']}", font=("Arial", 11)).pack(anchor="w", pady=2)
        ttk.Label(frame, text=f"时间: {schedule['start_time']}", font=("Arial", 11)).pack(anchor="w", pady=2)
        
        if schedule.get('description'):
            ttk.Label(frame, text=f"描述: {schedule['description']}", font=("Arial", 11)).pack(anchor="w", pady=2)
        
        # 按钮框架
        button_frame = ttk.Frame(frame)
        button_frame.pack(side=tk.BOTTOM, pady=10)
        
        def mark_completed():
            self.db_manager.update_schedule_status(schedule['id'], 'completed')
            self.reminder_service.mark_reminder_completed(schedule['id'])
            reminder_window.destroy()
            self.refresh_schedules()
        
        def snooze():
            self.reminder_service.mark_reminder_completed(schedule['id'])
            reminder_window.destroy()
        
        ttk.Button(button_frame, text="标记完成", command=mark_completed).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="稍后提醒", command=snooze).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="关闭", command=reminder_window.destroy).pack(side=tk.LEFT, padx=5)
    
    # =========================================================================
    # 公共方法 - 工具功能
    # =========================================================================
    
    def test_network(self):
        """测试网络通信"""
        if not self.net_sim.is_running:
            messagebox.showwarning("警告", "网络服务器未运行")
            return
        
        # 创建测试窗口
        test_window = tk.Toplevel(self.root)
        test_window.title("网络测试")
        test_window.geometry("400x300")
        test_window.transient(self.root)
        
        frame = ttk.Frame(test_window, padding="10")
        frame.pack(fill=tk.BOTH, expand=True)
        
        # 测试结果文本框
        text_area = scrolledtext.ScrolledText(frame, wrap=tk.WORD, width=40, height=15)
        text_area.pack(fill=tk.BOTH, expand=True, pady=5)
        text_area.config(state=tk.DISABLED)
        
        def run_tests():
            text_area.config(state=tk.NORMAL)
            text_area.delete(1.0, tk.END)
            text_area.insert(tk.END, "开始网络测试...\n\n")
            
            # 执行测试
            responses = self.net_sim.test_self_connection()
            
            for test_name, response in responses:
                if response.get("type") != "error":
                    text_area.insert(tk.END, f"✓ {test_name}: 成功\n")
                    text_area.insert(tk.END, f"   响应: {response}\n\n")
                else:
                    text_area.insert(tk.END, f"✗ {test_name}: 失败\n")
                    text_area.insert(tk.END, f"   错误: {response.get('message')}\n\n")
            
            # 显示服务器状态
            status = self.net_sim.get_server_status()
            text_area.insert(tk.END, f"服务器状态:\n")
            text_area.insert(tk.END, f"  运行状态: {'运行中' if status['is_running'] else '已停止'}\n")
            text_area.insert(tk.END, f"  端口: {status['port']}\n")
            text_area.insert(tk.END, f"  客户端数: {status['client_count']}\n")
            text_area.insert(tk.END, f"  消息数: {status['message_count']}\n")
            
            text_area.config(state=tk.DISABLED)
            test_button.config(state=tk.NORMAL)
        
        def start_test():
            test_button.config(state=tk.DISABLED)
            import threading
            thread = threading.Thread(target=run_tests)
            thread.daemon = True
            thread.start()
        
        # 测试按钮
        button_frame = ttk.Frame(frame)
        button_frame.pack(fill=tk.X, pady=5)
        
        test_button = ttk.Button(button_frame, text="开始测试", command=start_test)
        test_button.pack(side=tk.LEFT, padx=5)
        
        ttk.Button(button_frame, text="关闭", command=test_window.destroy).pack(side=tk.LEFT, padx=5)
    
    def create_backup(self):
        """创建系统备份"""
        from utils import create_system_backup
        backup_path = create_system_backup()
        if backup_path:
            messagebox.showinfo("备份成功", f"系统备份已创建:\n{backup_path}")
            self.status_var.set("系统备份已创建")
        else:
            messagebox.showerror("备份失败", "创建系统备份失败")
    
    def apply_system_settings(self):
        """应用系统设置"""
        try:
            # 更新提醒服务设置
            if self.reminder_service:
                check_interval = self.config.get("reminder.check_interval", 30)
                self.reminder_service.set_check_interval(check_interval)
                
                sound_enabled = self.config.get("reminder.play_sound", True)
                self.reminder_service.enable_sound(sound_enabled)
            
            # 更新窗口大小
            window_width = self.config.get("gui.window_width", 1000)
            window_height = self.config.get("gui.window_height", 700)
            self.root.geometry(f"{window_width}x{window_height}")
            
        except Exception as e:
            self.logger.error(f"应用系统设置失败: {e}")
    
    # =========================================================================
    # 公共方法 - 帮助和信息
    # =========================================================================
    
    def show_help(self):
        """显示使用说明"""
        help_text = """
智能日程管理助手 - 使用说明

基本操作:
1. 新建日程: 点击工具栏的"新建日程"按钮或使用Ctrl+N
2. 查看日程: 双击日程项查看详情，右键点击显示更多选项
3. 删除日程: 选中日程后点击"删除选中"或按Delete键
4. 搜索日程: 在工具栏搜索框中输入关键词后按回车

功能特性:
• 多线程智能提醒
• 数据导入导出
• 本地网络通信演示
• 数据统计和分析

快捷键:
• Ctrl+N: 新建日程
• Ctrl+Q: 退出程序
• F5: 刷新列表
• Delete: 删除选中日程
• Ctrl+F: 搜索日程

如有问题，请查看日志文件或联系开发者。
"""
        
        help_window = tk.Toplevel(self.root)
        help_window.title("使用说明")
        help_window.geometry("500x400")
        
        text_area = scrolledtext.ScrolledText(help_window, wrap=tk.WORD, padx=10, pady=10)
        text_area.pack(fill=tk.BOTH, expand=True)
        text_area.insert(tk.END, help_text)
        text_area.config(state=tk.DISABLED)
    
    def show_logs(self):
        """显示日志窗口"""
        log_window = tk.Toplevel(self.root)
        log_window.title("系统日志")
        log_window.geometry("600x400")
        
        # 创建文本框和滚动条
        text_area = scrolledtext.ScrolledText(log_window, wrap=tk.WORD)
        text_area.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # 加载日志
        self._load_logs_to_text(text_area)
        
        # 按钮框架
        button_frame = ttk.Frame(log_window)
        button_frame.pack(fill=tk.X, padx=5, pady=5)
        
        ttk.Button(button_frame, text="刷新", 
                  command=lambda: self._refresh_logs(text_area)).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="关闭", command=log_window.destroy).pack(side=tk.LEFT, padx=5)
    
    def _load_logs_to_text(self, text_area):
        """加载日志到文本框"""
        try:
            log_file = "data/logs/app.log"
            if os.path.exists(log_file):
                with open(log_file, 'r', encoding='utf-8') as f:
                    logs = f.read()
                    text_area.insert(tk.END, logs)
            else:
                text_area.insert(tk.END, "日志文件不存在或尚未生成。")
        except Exception as e:
            text_area.insert(tk.END, f"读取日志文件失败: {str(e)}")
        
        text_area.config(state=tk.DISABLED)
    
    def _refresh_logs(self, text_area):
        """刷新日志显示"""
        text_area.config(state=tk.NORMAL)
        text_area.delete(1.0, tk.END)
        self._load_logs_to_text(text_area)
    
    def show_about(self):
        """显示关于对话框"""
        from program_info import display_about
        about_text = display_about()
        
        about_window = tk.Toplevel(self.root)
        about_window.title("关于")
        about_window.geometry("300x250")
        about_window.resizable(False, False)
        about_window.transient(self.root)
        about_window.grab_set()
        
        text_widget = tk.Text(about_window, wrap=tk.WORD, padx=10, pady=10)
        text_widget.insert(tk.END, about_text)
        text_widget.config(state=tk.DISABLED)
        text_widget.pack(fill=tk.BOTH, expand=True)
        
        ttk.Button(about_window, text="确定", command=about_window.destroy).pack(pady=10)
    
    # =========================================================================
    # 公共方法 - 事件处理
    # =========================================================================
    
    def on_item_double_click(self, event):
        """处理日程项双击事件"""
        selection = self.tree.selection()
        if selection:
            item = self.tree.item(selection[0])
            values = item['values']
            schedule_id = values[0]
            self.show_edit_schedule_dialog(schedule_id)
    
    def on_right_click(self, event):
        """处理右键点击事件"""
        item = self.tree.identify_row(event.y)
        if item:
            self.tree.selection_set(item)
            
            # 创建右键菜单
            menu = tk.Menu(self.root, tearoff=0)
            menu.add_command(label="查看详情", 
                           command=lambda: self.show_schedule_detail(self.tree.item(item)['values'][0]))
            menu.add_command(label="编辑", 
                           command=lambda: self.show_edit_schedule_dialog(self.tree.item(item)['values'][0]))
            menu.add_command(label="删除", command=self.delete_selected_schedule)
            menu.add_separator()
            menu.add_command(label="标记为完成", 
                           command=lambda: self.mark_schedule_completed(self.tree.item(item)['values'][0]))
            
            # 显示菜单
            menu.post(event.x_root, event.y_root)
    
    def show_schedule_detail(self, schedule_id):
        """显示日程详情"""
        schedule = self.db_manager.get_schedule(schedule_id)
        if not schedule:
            messagebox.showerror("错误", "找不到指定的日程")
            return
        
        detail_window = tk.Toplevel(self.root)
        detail_window.title("日程详情")
        detail_window.geometry("400x300")
        detail_window.transient(self.root)
        detail_window.grab_set()
        
        # 创建详情内容
        frame = ttk.Frame(detail_window, padding="10")
        frame.pack(fill=tk.BOTH, expand=True)
        
        details = [
            ("标题:", schedule['title']),
            ("开始时间:", schedule['start_time']),
            ("结束时间:", schedule['end_time'] or "未设置"),
            ("优先级:", get_priority_text(schedule['priority'])),
            ("类别:", schedule['category']),
            ("状态:", schedule['status']),
            ("描述:", schedule['description'] or "无")
        ]
        
        for i, (label, value) in enumerate(details):
            ttk.Label(frame, text=label, font=("Arial", 10, "bold")).grid(row=i, column=0, sticky="w", pady=2)
            ttk.Label(frame, text=value, wraplength=300).grid(row=i, column=1, sticky="w", pady=2)
        
        # 按钮框架
        button_frame = ttk.Frame(frame)
        button_frame.grid(row=len(details), column=0, columnspan=2, pady=10)
        
        ttk.Button(button_frame, text="编辑", 
                  command=lambda: [detail_window.destroy(), self.show_edit_schedule_dialog(schedule_id)]).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="关闭", command=detail_window.destroy).pack(side=tk.LEFT, padx=5)
    
    def update_status_bar(self):
        """更新状态栏信息"""
        try:
            if self.reminder_service and self.reminder_service.is_alive():
                self.reminder_status_var.set("提醒服务: 运行中")
            else:
                self.reminder_status_var.set("提醒服务: 已停止")
            
            # 每秒更新一次
            self.root.after(1000, self.update_status_bar)
        except Exception as e:
            self.logger.error(f"更新状态栏失败: {e}")
    
    def on_closing(self):
        """处理窗口关闭事件"""
        if messagebox.askokcancel("退出", "确定要退出程序吗？"):
            # 停止提醒服务
            if self.reminder_service:
                self.reminder_service.stop()
            
            # 停止网络服务
            if self.net_sim:
                self.net_sim.stop_server()
            
            # 保存配置
            self.config._save_config()
            
            # 关闭程序
            self.root.destroy()
    
    def run(self):
        """启动GUI主循环"""
        self.logger.info("启动GUI主循环")
        self.root.mainloop()


# =============================================================================
# 对话框类 - 日程管理相关
# =============================================================================

class AddScheduleDialog:
    """添加日程对话框"""
    
    def __init__(self, parent, db_manager, config):
        self.parent = parent
        self.db_manager = db_manager
        self.config = config
        self.result = False
        
        self.dialog = tk.Toplevel(parent)
        self.dialog.title("添加新日程")
        self.dialog.geometry("400x400")
        self.dialog.transient(parent)
        self.dialog.grab_set()
        
        self._create_widgets()
        self.dialog.wait_window()
    
    def _create_widgets(self):
        """创建对话框控件"""
        main_frame = ttk.Frame(self.dialog, padding="10")
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 标题
        ttk.Label(main_frame, text="标题:*").grid(row=0, column=0, sticky="w", pady=5)
        self.title_entry = ttk.Entry(main_frame, width=30)
        self.title_entry.grid(row=0, column=1, columnspan=2, sticky="we", pady=5)
        
        # 开始时间
        ttk.Label(main_frame, text="开始时间:*").grid(row=1, column=0, sticky="w", pady=5)
        self.start_time_entry = ttk.Entry(main_frame, width=20)
        self.start_time_entry.grid(row=1, column=1, sticky="we", pady=5)
        # 设置为当前时间
        default_time = datetime.now().strftime("%Y-%m-%d %H:%M")
        self.start_time_entry.insert(0, default_time)
        
        # 结束时间
        ttk.Label(main_frame, text="结束时间:").grid(row=2, column=0, sticky="w", pady=5)
        self.end_time_entry = ttk.Entry(main_frame, width=20)
        self.end_time_entry.grid(row=2, column=1, sticky="we", pady=5)
        
        # 优先级
        ttk.Label(main_frame, text="优先级:").grid(row=3, column=0, sticky="w", pady=5)
        self.priority_var = tk.StringVar(value="中")
        priority_combo = ttk.Combobox(main_frame, textvariable=self.priority_var, 
                                     values=["低", "中", "高"], state="readonly")
        priority_combo.grid(row=3, column=1, sticky="we", pady=5)
        
        # 类别
        ttk.Label(main_frame, text="类别:").grid(row=4, column=0, sticky="w", pady=5)
        self.category_var = tk.StringVar(value="其他")
        category_combo = ttk.Combobox(main_frame, textvariable=self.category_var,
                                     values=["工作", "学习", "生活", "娱乐", "其他"], state="readonly")
        category_combo.grid(row=4, column=1, sticky="we", pady=5)
        
        # 提前提醒
        ttk.Label(main_frame, text="提前提醒(分钟):").grid(row=5, column=0, sticky="w", pady=5)
        self.reminder_var = tk.StringVar(value="15")
        reminder_spin = ttk.Spinbox(main_frame, from_=0, to=1440, textvariable=self.reminder_var, width=10)
        reminder_spin.grid(row=5, column=1, sticky="w", pady=5)
        
        # 描述
        ttk.Label(main_frame, text="描述:").grid(row=6, column=0, sticky="nw", pady=5)
        self.desc_text = tk.Text(main_frame, width=30, height=8)
        self.desc_text.grid(row=6, column=1, columnspan=2, sticky="nsew", pady=5)
        
        # 按钮
        button_frame = ttk.Frame(main_frame)
        button_frame.grid(row=7, column=0, columnspan=3, pady=10)
        
        ttk.Button(button_frame, text="确定", command=self._on_ok).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="取消", command=self._on_cancel).pack(side=tk.LEFT, padx=5)
        
        # 配置网格权重
        main_frame.columnconfigure(1, weight=1)
        main_frame.rowconfigure(6, weight=1)
    
    def _on_ok(self):
        """确定按钮处理"""
        title = self.title_entry.get().strip()
        start_time = self.start_time_entry.get().strip()
        end_time = self.end_time_entry.get().strip() or None
        
        # 数据验证
        errors = validate_schedule_data(title, start_time, end_time)
        if errors:
            messagebox.showerror("输入错误", "\n".join(errors))
            return
        
        # 转换优先级
        priority_map = {"低": 1, "中": 2, "高": 3}
        priority = priority_map.get(self.priority_var.get(), 2)
        
        category = self.category_var.get()
        description = self.desc_text.get("1.0", tk.END).strip()
        reminder_minutes = int(self.reminder_var.get())
        
        # 添加日程到数据库
        schedule_id = self.db_manager.add_schedule(
            title=title,
            start_time=start_time,
            end_time=end_time,
            priority=priority,
            category=category,
            description=description,
            reminder_minutes=reminder_minutes
        )
        
        if schedule_id:
            self.result = True
            self.dialog.destroy()
        else:
            messagebox.showerror("错误", "添加日程失败")
    
    def _on_cancel(self):
        """取消按钮处理"""
        self.dialog.destroy()


class EditScheduleDialog(AddScheduleDialog):
    """编辑日程对话框"""
    
    def __init__(self, parent, db_manager, schedule, config):
        self.schedule = schedule
        super().__init__(parent, db_manager, config)
        self.dialog.title("编辑日程")
        self._load_schedule_data()
    
    def _load_schedule_data(self):
        """加载日程数据到表单"""
        self.title_entry.delete(0, tk.END)
        self.title_entry.insert(0, self.schedule['title'])
        
        self.start_time_entry.delete(0, tk.END)
        self.start_time_entry.insert(0, self.schedule['start_time'])
        
        if self.schedule['end_time']:
            self.end_time_entry.delete(0, tk.END)
            self.end_time_entry.insert(0, self.schedule['end_time'])
        
        # 设置优先级
        priority_map = {1: "低", 2: "中", 3: "高"}
        self.priority_var.set(priority_map.get(self.schedule['priority'], "中"))
        
        self.category_var.set(self.schedule['category'])
        self.reminder_var.set(str(self.schedule['reminder_minutes']))
        
        self.desc_text.delete("1.0", tk.END)
        if self.schedule['description']:
            self.desc_text.insert("1.0", self.schedule['description'])
    
    def _on_ok(self):
        """确定按钮处理 - 更新日程"""
        title = self.title_entry.get().strip()
        start_time = self.start_time_entry.get().strip()
        end_time = self.end_time_entry.get().strip() or None
        
        # 数据验证
        errors = validate_schedule_data(title, start_time, end_time)
        if errors:
            messagebox.showerror("输入错误", "\n".join(errors))
            return
        
        # 转换优先级
        priority_map = {"低": 1, "中": 2, "高": 3}
        priority = priority_map.get(self.priority_var.get(), 2)
        
        category = self.category_var.get()
        description = self.desc_text.get("1.0", tk.END).strip()
        reminder_minutes = int(self.reminder_var.get())
        
        # 更新日程信息
        success = self.db_manager.update_schedule(
            self.schedule['id'],
            title=title,
            start_time=start_time,
            end_time=end_time,
            priority=priority,
            category=category,
            description=description,
            reminder_minutes=reminder_minutes
        )
        
        if success:
            self.result = True
            self.dialog.destroy()
        else:
            messagebox.showerror("错误", "更新日程失败")


class SearchDialog:
    """搜索对话框"""
    
    def __init__(self, parent, db_manager):
        self.parent = parent
        self.db_manager = db_manager
        self.result = None
        
        self.dialog = tk.Toplevel(parent)
        self.dialog.title("搜索日程")
        self.dialog.geometry("350x150")
        self.dialog.transient(parent)
        self.dialog.grab_set()
        
        self._create_widgets()
        self.dialog.wait_window()
    
    def _create_widgets(self):
        """创建对话框控件"""
        main_frame = ttk.Frame(self.dialog, padding="15")
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 搜索关键词
        ttk.Label(main_frame, text="搜索关键词:", font=("Arial", 10, "bold")).pack(anchor="w", pady=5)
        
        self.keyword_var = tk.StringVar()
        keyword_entry = ttk.Entry(main_frame, textvariable=self.keyword_var, width=30)
        keyword_entry.pack(fill=tk.X, pady=5)
        keyword_entry.focus()
        
        # 搜索提示
        ttk.Label(main_frame, text="支持搜索标题和描述中的关键词", 
                 font=("Arial", 8), foreground="gray").pack(anchor="w", pady=2)
        
        # 按钮框架
        button_frame = ttk.Frame(main_frame)
        button_frame.pack(side=tk.BOTTOM, pady=10)
        
        ttk.Button(button_frame, text="搜索", command=self._on_search).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="取消", command=self._on_cancel).pack(side=tk.LEFT, padx=5)
        
        # 绑定回车键
        keyword_entry.bind("<Return>", lambda e: self._on_search())
    
    def _on_search(self):
        """搜索按钮处理"""
        keyword = self.keyword_var.get().strip()
        if not keyword:
            messagebox.showwarning("输入错误", "请输入搜索关键词")
            return
        
        self.result = {'keyword': keyword}
        self.dialog.destroy()
    
    def _on_cancel(self):
        """取消按钮处理"""
        self.dialog.destroy()


# =============================================================================
# 对话框类 - 系统功能相关
# =============================================================================

class ExportDialog:
    """导出对话框"""
    
    def __init__(self, parent, file_exporter):
        self.parent = parent
        self.file_exporter = file_exporter
        self.result = False
        
        self.dialog = tk.Toplevel(parent)
        self.dialog.title("导出日程")
        self.dialog.geometry("300x200")
        self.dialog.transient(parent)
        self.dialog.grab_set()
        
        self._create_widgets()
        self.dialog.wait_window()
    
    def _create_widgets(self):
        """创建对话框控件"""
        main_frame = ttk.Frame(self.dialog, padding="15")
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        ttk.Label(main_frame, text="选择导出格式:", font=("Arial", 10, "bold")).pack(anchor="w", pady=5)
        
        # 导出格式选择
        self.format_var = tk.StringVar(value="json")
        
        formats = [
            ("JSON 格式", "json"),
            ("CSV 格式", "csv"), 
            ("文本格式", "text"),
            ("所有格式", "all")
        ]
        
        for text, value in formats:
            ttk.Radiobutton(main_frame, text=text, variable=self.format_var, value=value).pack(anchor="w", pady=2)
        
        # 日期选择
        ttk.Label(main_frame, text="导出日期:", font=("Arial", 10, "bold")).pack(anchor="w", pady=(15, 5))
        
        self.date_var = tk.StringVar(value=datetime.now().strftime("%Y-%m-%d"))
        date_entry = ttk.Entry(main_frame, textvariable=self.date_var, width=12)
        date_entry.pack(anchor="w", pady=2)
        ttk.Label(main_frame, text="格式: YYYY-MM-DD (留空为今日)").pack(anchor="w")
        
        # 按钮
        button_frame = ttk.Frame(main_frame)
        button_frame.pack(side=tk.BOTTOM, pady=10)
        
        ttk.Button(button_frame, text="导出", command=self._on_export).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="取消", command=self.dialog.destroy).pack(side=tk.LEFT, padx=5)
    
    def _on_export(self):
        """执行导出"""
        date_str = self.date_var.get().strip()
        if not date_str:
            date_str = datetime.now().strftime("%Y-%m-%d")
        
        format_type = self.format_var.get()
        
        def export_callback(success, path, message):
            if success:
                messagebox.showinfo("导出成功", message)
                if path:
                    messagebox.showinfo("导出完成", f"文件已保存到:\n{path}")
            else:
                messagebox.showerror("导出失败", message)
        
        if format_type == "json":
            self.file_exporter.export_to_json(date_str, export_callback)
        elif format_type == "csv":
            self.file_exporter.export_to_csv(date_str, export_callback)
        elif format_type == "text":
            self.file_exporter.export_to_text(date_str, export_callback)
        elif format_type == "all":
            self.file_exporter.export_all_formats(date_str, export_callback)
        
        self.result = True
        self.dialog.destroy()


class ReminderSettingsDialog:
    """提醒设置对话框"""
    
    def __init__(self, parent, reminder_service, config):
        self.parent = parent
        self.reminder_service = reminder_service
        self.config = config
        self.result = False
        
        self.dialog = tk.Toplevel(parent)
        self.dialog.title("提醒设置")
        self.dialog.geometry("300x250")
        self.dialog.transient(parent)
        self.dialog.grab_set()
        
        self._create_widgets()
        self.dialog.wait_window()
    
    def _create_widgets(self):
        """创建对话框控件"""
        main_frame = ttk.Frame(self.dialog, padding="15")
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        ttk.Label(main_frame, text="提醒设置", font=("Arial", 12, "bold")).grid(row=0, column=0, columnspan=2, pady=10)
        
        # 检查间隔
        ttk.Label(main_frame, text="检查间隔(秒):").grid(row=1, column=0, sticky="w", pady=5)
        self.interval_var = tk.StringVar(value=str(self.config.get("reminder.check_interval", 30)))
        interval_spin = ttk.Spinbox(main_frame, from_=10, to=3600, textvariable=self.interval_var, width=10)
        interval_spin.grid(row=1, column=1, sticky="w", pady=5)
        
        # 默认提前提醒时间
        ttk.Label(main_frame, text="默认提前提醒(分钟):").grid(row=2, column=0, sticky="w", pady=5)
        self.advance_var = tk.StringVar(value=str(self.config.get("reminder.default_advance_minutes", 15)))
        advance_spin = ttk.Spinbox(main_frame, from_=0, to=1440, textvariable=self.advance_var, width=10)
        advance_spin.grid(row=2, column=1, sticky="w", pady=5)
        
        # 声音提醒
        self.sound_var = tk.BooleanVar(value=self.config.get("reminder.play_sound", True))
        ttk.Checkbutton(main_frame, text="启用声音提醒", variable=self.sound_var).grid(row=3, column=0, columnspan=2, sticky="w", pady=5)
        
        # 按钮
        button_frame = ttk.Frame(main_frame)
        button_frame.grid(row=4, column=0, columnspan=2, pady=15)
        
        ttk.Button(button_frame, text="保存", command=self._on_save).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="取消", command=self._on_cancel).pack(side=tk.LEFT, padx=5)
    
    def _on_save(self):
        """保存设置"""
        try:
            # 验证输入
            interval = int(self.interval_var.get())
            advance = int(self.advance_var.get())
            
            if interval < 10 or interval > 3600:
                messagebox.showerror("输入错误", "检查间隔必须在10-3600秒之间")
                return
            
            if advance < 0 or advance > 1440:
                messagebox.showerror("输入错误", "提前提醒时间必须在0-1440分钟之间")
                return
            
            # 保存到配置
            self.config.set("reminder.check_interval", interval)
            self.config.set("reminder.default_advance_minutes", advance)
            self.config.set("reminder.play_sound", self.sound_var.get())
            
            # 应用到提醒服务
            if self.reminder_service:
                self.reminder_service.set_check_interval(interval)
                self.reminder_service.enable_sound(self.sound_var.get())
            
            self.result = True
            self.dialog.destroy()
            
        except ValueError:
            messagebox.showerror("输入错误", "请输入有效的数字")
    
    def _on_cancel(self):
        """取消按钮处理"""
        self.dialog.destroy()


class SystemSettingsDialog:
    """系统设置对话框"""
    
    def __init__(self, parent, config):
        self.parent = parent
        self.config = config
        self.result = False
        
        self.dialog = tk.Toplevel(parent)
        self.dialog.title("系统设置")
        self.dialog.geometry("350x300")
        self.dialog.transient(parent)
        self.dialog.grab_set()
        
        self._create_widgets()
        self.dialog.wait_window()
    
    def _create_widgets(self):
        """创建对话框控件"""
        main_frame = ttk.Frame(self.dialog, padding="15")
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        ttk.Label(main_frame, text="系统设置", font=("Arial", 12, "bold")).grid(row=0, column=0, columnspan=2, pady=10)
        
        # 日志级别
        ttk.Label(main_frame, text="日志级别:").grid(row=1, column=0, sticky="w", pady=5)
        self.log_level_var = tk.StringVar(value=self.config.get("system.log_level", "INFO"))
        log_level_combo = ttk.Combobox(main_frame, textvariable=self.log_level_var,
                                      values=["DEBUG", "INFO", "WARNING", "ERROR"], state="readonly")
        log_level_combo.grid(row=1, column=1, sticky="w", pady=5)
        
        # 自动备份
        self.backup_var = tk.BooleanVar(value=self.config.get("database.backup_on_start", True))
        ttk.Checkbutton(main_frame, text="启动时自动备份数据库", variable=self.backup_var).grid(row=2, column=0, columnspan=2, sticky="w", pady=5)
        
        # 自动清理天数
        ttk.Label(main_frame, text="自动清理旧数据(天):").grid(row=3, column=0, sticky="w", pady=5)
        self.cleanup_var = tk.StringVar(value=str(self.config.get("database.auto_cleanup_days", 30)))
        cleanup_spin = ttk.Spinbox(main_frame, from_=0, to=365, textvariable=self.cleanup_var, width=10)
        cleanup_spin.grid(row=3, column=1, sticky="w", pady=5)
        
        # 最大备份文件数
        ttk.Label(main_frame, text="最大备份文件数:").grid(row=4, column=0, sticky="w", pady=5)
        self.max_backup_var = tk.StringVar(value=str(self.config.get("system.max_backup_files", 10)))
        max_backup_spin = ttk.Spinbox(main_frame, from_=1, to=100, textvariable=self.max_backup_var, width=10)
        max_backup_spin.grid(row=4, column=1, sticky="w", pady=5)
        
        # 网络服务器
        self.network_var = tk.BooleanVar(value=self.config.get("network.auto_start_server", True))
        ttk.Checkbutton(main_frame, text="启动时自动运行网络服务器", variable=self.network_var).grid(row=5, column=0, columnspan=2, sticky="w", pady=5)
        
        # 按钮
        button_frame = ttk.Frame(main_frame)
        button_frame.grid(row=6, column=0, columnspan=2, pady=15)
        
        ttk.Button(button_frame, text="保存", command=self._on_save).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="取消", command=self._on_cancel).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="恢复默认", command=self._on_reset).pack(side=tk.LEFT, padx=5)
    
    def _on_save(self):
        """保存设置"""
        try:
            # 验证输入
            cleanup_days = int(self.cleanup_var.get())
            max_backups = int(self.max_backup_var.get())
            
            if cleanup_days < 0 or cleanup_days > 365:
                messagebox.showerror("输入错误", "自动清理天数必须在0-365之间")
                return
            
            if max_backups < 1 or max_backups > 100:
                messagebox.showerror("输入错误", "最大备份文件数必须在1-100之间")
                return
            
            # 保存到配置
            self.config.set("system.log_level", self.log_level_var.get())
            self.config.set("database.backup_on_start", self.backup_var.get())
            self.config.set("database.auto_cleanup_days", cleanup_days)
            self.config.set("system.max_backup_files", max_backups)
            self.config.set("network.auto_start_server", self.network_var.get())
            
            self.result = True
            self.dialog.destroy()
            
        except ValueError:
            messagebox.showerror("输入错误", "请输入有效的数字")
    
    def _on_reset(self):
        """恢复默认设置"""
        if messagebox.askyesno("确认", "确定要恢复默认设置吗？"):
            self.config.reset_to_defaults()
            self.result = True
            self.dialog.destroy()
    
    def _on_cancel(self):
        """取消按钮处理"""
        self.dialog.destroy()


# =============================================================================
# 测试函数
# =============================================================================

def test_gui():
    """测试GUI功能"""
    import tempfile
    
    print("测试GUI界面...")
    
    # 使用临时数据库
    temp_db = tempfile.NamedTemporaryFile(delete=False, suffix='.db')
    temp_db.close()
    
    try:
        from database import DatabaseManager
        from config import ConfigManager
        from network_sim import NetworkSimulator
        from reminder_service import ReminderManager
        from file_export import FileExporter
        
        # 初始化各个模块
        config = ConfigManager()
        db = DatabaseManager(temp_db.name)
        net_sim = NetworkSimulator(port=8889)
        reminder_manager = ReminderManager(db)
        file_exporter = FileExporter(db)
        
        # 添加测试数据
        db.add_schedule("测试日程1", "2024-01-01 10:00:00", "测试描述1")
        db.add_schedule("测试日程2", "2024-01-01 14:00:00", "测试描述2")
        
        # 创建GUI
        app = ScheduleGUI(db, net_sim, reminder_manager, file_exporter, config)
        
        print("GUI创建成功，将在5秒后关闭...")
        
        # 5秒后自动关闭测试窗口
        app.root.after(5000, app.root.destroy)
        
        # 运行GUI
        app.run()
        
        print("GUI测试完成!")
        
    except Exception as e:
        print(f"GUI测试失败: {e}")
        import traceback
        traceback.print_exc()
    finally:
        # 清理临时文件
        if os.path.exists(temp_db.name):
            os.unlink(temp_db.name)


if __name__ == "__main__":
    # 配置日志
    logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    
    # 测试GUI
    test_gui()